package com.zbkj.crmeb.chant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.constants.Constants;
import com.github.pagehelper.PageHelper;
import com.utils.DateUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.chant.dao.ChannelProductBatchInfoDao;
import com.zbkj.crmeb.chant.model.ChannelProductBatchInfo;
import com.zbkj.crmeb.chant.model.ChannelProductBatchRecord;
import com.zbkj.crmeb.chant.request.ChannelProductBatchInfoRequest;
import com.zbkj.crmeb.chant.response.ChannelProductBatchInfoResponse;
import com.zbkj.crmeb.chant.service.ChannelProductBatchInfoService;
import com.zbkj.crmeb.chant.service.ChannelProductBatchRecordService;
import com.zbkj.crmeb.enums.ProductTypeEnum;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.system.model.SystemAdmin;
import com.zbkj.crmeb.system.service.SystemAdminService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChannelProductBatchInfoServiceImpl extends ServiceImpl<ChannelProductBatchInfoDao, ChannelProductBatchInfo> implements ChannelProductBatchInfoService {

    @Autowired
    private SupplierService supplierService;
    @Autowired
    private ChannelProductBatchRecordService channelProductBatchRecordService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private SystemAdminService systemAdminService;
    @Autowired
    private StoreProductDescriptionService storeProductDescriptionService;
    @Autowired
    private StoreProductMerService storeProductMerService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private StoreBrandService storeBrandService;

    /**
     * 功能描述: 批量更新商品
     *
     * @Param: [requests, merId]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/3/21 14:03
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateBatchProduct(List<ChannelProductBatchInfoRequest> requests, Integer merId) {
        ChannelProductBatchInfo info = new ChannelProductBatchInfo();
        info.setMerId(merId).setOperationId("XG" + DateUtil.nowDate(Constants.DATE_TIME_FORMAT_NUM) + (int) (Math.random() * (99999 - 11111 + 1) + 11111));
        List<String> names = getNotNullParameterName(requests.get(0));
        // 字段跟中文对应
        Map<String, String> map = new HashMap<>();
        map.put("storeName", "商品名称");
        map.put("status", "商品状态");
        map.put("brandId", "品牌");
        map.put("unitName", "单位");
        map.put("tempId", "发货地");
        map.put("deliveryData", "预计发货时间");
        map.put("earliestArrivalData", "预计到货时间");
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : names) {
            stringBuilder.append(map.get(s));
            stringBuilder.append(" ");
        }
        stringBuilder.deleteCharAt(stringBuilder.lastIndexOf(" "));
        info.setOperationMsg(stringBuilder.toString().replace("null", ""));
        info.setProductNumber(requests.size());
        info.setOperationUserId(systemAdminService.getAdminId());
        this.saveOrUpdate(info);
        // 失败数
        Integer number = checkProductInfo(requests, merId, info.getId());
        info.setFailNumber(number);
        // 批量修改商品全部不符合前置条件
        if (CollectionUtils.isEmpty(requests)) {
            // 保存失败商品数
            this.saveOrUpdate(info);
            return true;
        }
        // 批量修改的所有品牌id
        List<Integer> brandIds = requests.stream().map(ChannelProductBatchInfoRequest::getBrandId).distinct().collect(Collectors.toList());
        // 品牌id与名称映射关系
        Map<Integer, String> brandNameMap = storeBrandService.getBrandNameMap(brandIds);
        // 修改的商品id
        List<Integer> productIds = requests.stream().map(ChannelProductBatchInfoRequest::getProductId).distinct().collect(Collectors.toList());
        // 每个商品对应的规格列表
        List<StoreProductAttrValue> attrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery().in(StoreProductAttrValue::getProductId, productIds));
        Map<Integer, List<StoreProductAttrValue>> attrValueMap = attrValues.stream().collect(Collectors.groupingBy(StoreProductAttrValue::getProductId));
        // 商品描述
        List<StoreProductDescription> storeProductDescriptions = storeProductDescriptionService.list(Wrappers.<StoreProductDescription>lambdaQuery().in(StoreProductDescription::getProductId, productIds));
        Map<Integer, List<StoreProductDescription>> storeProductDescriptionMap = storeProductDescriptions.stream().collect(Collectors.groupingBy(StoreProductDescription::getProductId));
        // 商户对商品的配置
        List<StoreProductMer> storeProductMers = storeProductMerService.list(Wrappers.<StoreProductMer>lambdaQuery().in(StoreProductMer::getProductId, productIds));
        Map<Integer, List<StoreProductMer>> storeProductMerMap = storeProductMers.stream().collect(Collectors.groupingBy(StoreProductMer::getProductId));
        // 待修改的商品
        List<StoreProduct> storeProducts = new ArrayList<>();
        // 待添加的日志
        List<ChannelProductBatchRecord> ChannelProductBatchRecords = new ArrayList<>();
        for (ChannelProductBatchInfoRequest request : requests) {
            // 商品名称 上下架 品牌 发货地 修改在storeProduct表
            StoreProduct storeProduct = new StoreProduct();
            storeProduct.setId(request.getProductId());
            storeProduct.setStoreName(request.getStoreName());
            storeProduct.setIsShow(request.getStatus());
            storeProduct.setBrandId(request.getBrandId());
            storeProduct.setBrandName(brandNameMap.get(request.getBrandId()));
            storeProduct.setTempId(request.getTempId());
            storeProducts.add(storeProduct);
            // 规格也存在发货地
            attrValueMap.get(request.getProductId()).forEach(e -> e.setTempId(request.getTempId()));
            // 单位修改
            storeProductDescriptionMap.get(request.getProductId()).forEach(e -> e.setUnitName(request.getUnitName()));
            // 预计到货时间以及最早到货时间 最慢到货时间修改
            if (names.contains("deliveryData") || names.contains("earliestArrivalData")) {
                if (Objects.nonNull(storeProductMerMap.get(request.getProductId()))) {
                    storeProductMerMap.get(request.getProductId()).forEach(e -> e.setDeliveryData(request.getDeliveryData()).setEarliestArrivalData(request.getEarliestArrivalData()).setSlowestArrivalData(request.getSlowestArrivalData()));
                } else {
                    StoreProductMer storeProductMer = new StoreProductMer();
                    storeProductMer.setProductId(request.getProductId());
                    storeProductMer.setDeliveryData(request.getDeliveryData());
                    storeProductMer.setEarliestArrivalData(request.getEarliestArrivalData());
                    storeProductMer.setSlowestArrivalData(request.getSlowestArrivalData());
                    storeProductMers.add(storeProductMer);
                }
            }
            // 添加商品操作日志
            ChannelProductBatchRecord channelProductBatchRecord = new ChannelProductBatchRecord();
            BeanUtils.copyProperties(request, channelProductBatchRecord);
            channelProductBatchRecord.setInfoId(info.getId());
            ChannelProductBatchRecords.add(channelProductBatchRecord);
        }
        // 保存操作日志
        this.saveOrUpdate(info);
        channelProductBatchRecordService.saveBatch(ChannelProductBatchRecords);
        if (names.contains("deliveryData") || names.contains("earliestArrivalData")) {
            storeProductMerService.saveOrUpdateBatch(storeProductMers);
        }
        if (names.contains("unitName")) {
            storeProductDescriptionService.updateBatchById(storeProductDescriptions);
        }
        if (names.contains("tempId")) {
            storeProductAttrValueService.updateBatchByQueryWrapper(attrValues, storeProductAttrValue -> Wrappers.<StoreProductAttrValue>lambdaQuery().eq(StoreProductAttrValue::getProductId, storeProductAttrValue.getProductId()));
        }
        if (names.contains("storeName") || names.contains("status") || names.contains("brandId") || names.contains("tempId")) {
            storeProductService.updateBatchById(storeProducts);
        }
        return true;
    }

    /**
     * 功能描述: 查询批量修改列表
     *
     * @Param: [request, merId]
     * @Return: java.util.List<com.zbkj.crmeb.chant.model.ChannelProductBatchInfo>
     * @Author: wangzh
     * @Date: 2023/3/21 14:36
     */
    @Override
    public List<ChannelProductBatchInfoResponse> getList(ChannelProductBatchInfoRequest request, Integer merId) {
        List<ChannelProductBatchInfoResponse> responses = new ArrayList<>();
        LambdaQueryWrapper<ChannelProductBatchInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChannelProductBatchInfo::getMerId, merId);
        // 操作时间查询
        if (StringUtils.isNotBlank(request.getCreateTime())) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getCreateTime());
            queryWrapper.le(ChannelProductBatchInfo::getCreateTime, dateLimit.getEndTime());
            queryWrapper.ge(ChannelProductBatchInfo::getCreateTime, dateLimit.getStartTime());
        }
        Map<Integer, String> adminNameMap = new HashMap<>();
        // 操作人筛选
        if (Objects.nonNull(request.getOperationUserId())) {
            queryWrapper.eq(ChannelProductBatchInfo::getOperationUserId, request.getOperationUserId());
            SystemAdmin systemAdmin = systemAdminService.getOne(Wrappers.<SystemAdmin>lambdaQuery().eq(SystemAdmin::getId, request.getOperationUserId()));
            if (Objects.nonNull(systemAdmin)) {
                adminNameMap.put(request.getOperationUserId(), systemAdmin.getAccount());
            }
        }
        queryWrapper.orderByDesc(ChannelProductBatchInfo::getId);
        PageHelper.startPage(request.getPage(), request.getLimit());
        List<ChannelProductBatchInfo> channelProductBatchInfos = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(channelProductBatchInfos)) {
            return responses;
        }
        // 查询操作人名称
        if (Objects.isNull(request.getOperationUserId())) {
            List<Integer> adminIds = channelProductBatchInfos.stream().map(ChannelProductBatchInfo::getOperationUserId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(adminIds)) {
                adminNameMap = systemAdminService.list(Wrappers.<SystemAdmin>lambdaQuery().in(SystemAdmin::getId, adminIds)).stream().collect(Collectors.toMap(SystemAdmin::getId, SystemAdmin::getAccount));
            }
        }

        for (ChannelProductBatchInfo channelProductBatchInfo : channelProductBatchInfos) {
            ChannelProductBatchInfoResponse response = new ChannelProductBatchInfoResponse();
            BeanUtils.copyProperties(channelProductBatchInfo, response);
            response.setOperationUser(adminNameMap.get(channelProductBatchInfo.getOperationUserId()));
            responses.add(response);
        }

        return responses;
    }

    /**
     * 功能描述: 返回操作人列表
     * @Param: [merId]
     * @Return: java.util.Map<java.lang.Integer,java.lang.String>
     * @Author: wangzh
     * @Date: 2023/3/21 17:54
     */
    @Override
    public Map<Integer, String> getOperationUserMap(Integer merId) {
        List<ChannelProductBatchInfo> channelProductBatchInfos = this.list(Wrappers.<ChannelProductBatchInfo>lambdaQuery()
                .eq(ChannelProductBatchInfo::getMerId, merId));
        if (CollectionUtils.isEmpty(channelProductBatchInfos)) {
            return null;
        }
        List<Integer> adminIds = channelProductBatchInfos.stream().map(ChannelProductBatchInfo::getOperationUserId).distinct().collect(Collectors.toList());
        return systemAdminService.list(Wrappers.<SystemAdmin>lambdaQuery().in(SystemAdmin::getId, adminIds)).stream().collect(Collectors.toMap(SystemAdmin::getId, SystemAdmin::getAccount));
    }

    /**
     * 功能描述: 对批量修改的商品信息进行检查，并生成日志
     *
     * @Param: [requests, merId, infoId]
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/3/20 15:33
     */
    private Integer checkProductInfo(List<ChannelProductBatchInfoRequest> requests, Integer merId, Integer infoId) {
        List<ChannelProductBatchRecord> channelProductBatchRecords = new ArrayList<>();
        Iterator<ChannelProductBatchInfoRequest> iterator = requests.iterator();
        while (iterator.hasNext()) {
            ChannelProductBatchInfoRequest request = iterator.next();
            ChannelProductBatchRecord channelProductBatchRecord = new ChannelProductBatchRecord();
            BeanUtils.copyProperties(request, channelProductBatchRecord);
            channelProductBatchRecord.setInfoId(infoId);
            // 商户是否具有自建商品权限
            Supplier supplier = supplierService.getSupplierBarcode(merId);
            // 检查商品是否存在
            StoreProduct storeProduct = storeProductService.getById(request.getProductId());
            boolean flag = false;
            // 发货时间判断
            if (Objects.nonNull(request.getEarliestArrivalData()) && Objects.nonNull(request.getSlowestArrivalData())) {
                if (request.getEarliestArrivalData() >= request.getSlowestArrivalData()) {
                    channelProductBatchRecord.setBatchStatus(false);
                    channelProductBatchRecord.setFailMsg("最慢到货天数必须大于最快到货天数");
                    iterator.remove();
                    channelProductBatchRecords.add(channelProductBatchRecord);
                    continue;
                }
            }
            if (null == supplier) {
                channelProductBatchRecord.setBatchStatus(false);
                channelProductBatchRecord.setFailMsg("请给商户创建供应商后再添加商品");
                flag = true;
            } else if (null == storeProduct) {
                channelProductBatchRecord.setBatchStatus(false);
                channelProductBatchRecord.setFailMsg("商品不存在");
                flag = true;
                // 检查是否当前商户自建商品
            } else if (!Objects.equals(ProductTypeEnum.INSIDE.getCode(), storeProduct.getIsEurope()) && !Objects.equals(merId, storeProduct.getMerId())) {
                channelProductBatchRecord.setBatchStatus(false);
                channelProductBatchRecord.setFailMsg("只能修改自己新增的商品！");
                flag = true;
            }
            // 是否有一个条件不满足
            if (flag) {
                iterator.remove();
                channelProductBatchRecords.add(channelProductBatchRecord);
            }
        }
        // 保存失败商品的记录
        channelProductBatchRecordService.saveBatch(channelProductBatchRecords);
        return channelProductBatchRecords.size();
    }

    /**
     * 功能描述: 获取不为空的字段
     *
     * @Param: [request]
     * @Return: java.util.List<java.lang.String>
     * @Author: wangzh
     * @Date: 2023/3/20 17:54
     */
    private List<String> getNotNullParameterName(ChannelProductBatchInfoRequest request) {
        List<String> names = new ArrayList<>();
        Field[] declaredFields = request.getClass().getDeclaredFields();
        try {
            for (Field field : declaredFields) {
                field.setAccessible(true);
                if (Objects.nonNull(field.get(request))) {
                    names.add(field.getName());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return names;
    }
}
